发布订阅模式
事件发布/订阅模式 (PubSub) 在异步编程中帮助我们完成更松的解耦, 甚至在 MVC、MVVC 的架构中以及设计模式中也少不了发布-订阅模式的参与。
优点: 在异步编程中实现更深的解耦
缺点: 如果过多的使用发布订阅模式, 会增加维护的难度
实现一个发布订阅模式
var Event = function() {
this.obj = {}
}
Event.prototype.on = function(eventType,fn){
if(!this.obj[eventType]) {
this.obj[eventType]=[]
}
this.obj[eventType].push(fn) //这边方法函数放进去
}
Event.prototype.emit =function() {
var eventType = Array.prototype.shift.call(arguments)
var arr = this.obj[eventType] //这边方法函数取出来
for(let i =0;i<arr.length; i++){
arr[i].apply(arr[i],arguments) //把emit的值赋值 on中的函数 打印出来
}
}
var ev = new Event()
ev.on('click',function(a){ //订阅函数
console.log(a) //5
})
ev.emit('click',5)
订阅函数逻辑一定要优先于发布函数吗
考虑以下场景:
$.ajax('', () => {
// 异步订阅函数逻辑
})
// 在其他地方执行发布函数, 此时并不能保证执行发布函数的时候, 订阅函数已经执行
那么就应该这样做
var Event = function () {
this.obj = {}
this.cacheList = []
}
Event.prototype.on = function (eventType, fn) {
if (!this.obj[eventType]) {
this.obj[eventType] = []
}
this.obj[eventType].push(fn)
for (let i = 0; i < this.cacheList.length; i++) {
this.cacheList[i]() //on中触发cacheList里面储存的函数
}
}
Event.prototype.emit = function () {
var arg = arguments
var that = this
function cache() {
var eventType = Array.prototype.shift.call(arg)
var arr = that.obj[eventType]
for (let i = 0; i < arr.length; i++) {
arr[i].apply(arr[i], arg)
}
}
this.cacheList.push(cache) //emit触发的函数保存到cacheList中
//转交给on中去触发, 从而实现发布函数先于订阅函数执行
}
var ev = new Event()
ev.emit('click', 5) //这个使用的前提是 一定是先触发订阅
//然后等待 发布函数中的cacheList[i]()方法执行
ev.on('click', function (a) {
console.log(a)
})
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。